package com.ganzalang.gmall.promotion.service.impl;

import com.alibaba.fastjson.JSON;
import com.ganzalang.gmall.promotion.dto.*;
import com.ganzalang.gmall.promotion.exceptions.PromotionException;
import com.ganzalang.gmall.promotion.service.RuleService;
import com.ganzalang.gmall.promotion.service.rule.condition.EnjoyConditionStrategy;
import com.ganzalang.gmall.promotion.service.rule.condition.factory.EnjoyConditionFactory;
import com.ganzalang.gmall.promotion.dto.config.CommonConfig;
import com.ganzalang.gmall.promotion.service.rule.profit.ProfitStrategy;
import com.ganzalang.gmall.promotion.service.rule.profit.factory.ProfitFactory;
import com.ganzalang.gmall.promotion.service.rule.qualify.QualifyStrategy;
import com.ganzalang.gmall.promotion.service.rule.qualify.factory.QualifyFactory;
import com.ganzalang.gmall.promotion.service.rule.target.TargetStrategy;
import com.ganzalang.gmall.promotion.service.rule.target.factory.TargetFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author Ganzalang
 * @description 校验规则的实现类
 * @Date 2022/4/3 23:08
 */
@Service
@RequiredArgsConstructor
public class RuleServiceImpl implements RuleService {


    /**
     * 校验规则
     *
     * @param context 规则上下文
     * @return
     */
    @Override
    public RuleResult validateRule(RuleContext context) {
        RuleResult result = new RuleResult();
        DiscountDTO discountDTO = context.getCartPromotionItem().getDiscountDTO();

        // 资格校验
        CommonConfig qualifyCommon = JSON.parseObject(discountDTO.getQualifyConfig(), CommonConfig.class);
        QualifyResult qualifyResult = new QualifyResult();
        if (Objects.nonNull(qualifyCommon)) {
            QualifyStrategy qualifyStrategy = QualifyFactory.getBean(qualifyCommon.getType());
            qualifyResult = qualifyStrategy.qualify(context);
        }

        // 有资格
        if (qualifyResult.isQualify()) {
            // 找出符合的目标商品
            TargetStrategy targetStrategy = TargetFactory.getBean(discountDTO.getAvailableRange());
            TargetResult targetResult = targetStrategy.acquireTarget(context);

            // 判断是否满足促销活动的条件
            CommonConfig ruleCommon = JSON.parseObject(discountDTO.getRuleConfig(), CommonConfig.class);
            EnjoyConditionStrategy enjoyConditionStrategy = EnjoyConditionFactory.getBean(ruleCommon.getType());
            EnjoyConditionResult enjoyConditionResult = enjoyConditionStrategy.validate(targetResult);

            if (!enjoyConditionResult.isEnjoy()) {
                // 不满足则抛异常
                throw PromotionException.NOT_ENJOY_CONDITION;
            }

            ProfitStrategy profitStrategy = ProfitFactory.getBean(discountDTO.getChargeType());
            result = profitStrategy.calculate(enjoyConditionResult);
        }

        return result;
    }
}
